package com.ruoyi.contrctrefund.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.ruoyi.applyrecord.domain.HouseContarctApplyRecord;
import com.ruoyi.applyrecord.enums.ContarctOperResType;
import com.ruoyi.applyrecord.enums.ContarctOperType;
import com.ruoyi.applyrecord.mapper.HouseContarctApplyRecordMapper;
import com.ruoyi.contarct.domain.HouseContarct;
import com.ruoyi.contarct.enums.ContarctStatusType;
import com.ruoyi.contarct.mapper.HouseContarctMapper;
import com.ruoyi.contarct.service.IHouseContarctService;
import com.ruoyi.contarctbill.domain.HouseContarctBill;
import com.ruoyi.contarctbill.enums.BillRefundStatusType;
import com.ruoyi.contarctbill.enums.BillStatusType;
import com.ruoyi.contarctbill.enums.BillType;
import com.ruoyi.contarctbill.enums.ContarctBillSettleType;
import com.ruoyi.contarctbill.mapper.HouseContarctBillMapper;
import com.ruoyi.contrctrefund.enums.RefundApplyType;
import com.ruoyi.house.domain.HouseInfo;
import com.ruoyi.house.enums.HouseMarketableType;
import com.ruoyi.house.enums.HouseStatusType;
import com.ruoyi.house.mapper.HouseInfoMapper;
import com.ruoyi.income.domain.HouseContarctIncome;
import com.ruoyi.income.mapper.HouseContarctIncomeMapper;
import com.ruoyi.income.service.IHouseContarctIncomeService;
import com.ruoyi.refundincome.domain.HouseContrctRefundIncome;
import com.ruoyi.refundincome.mapper.HouseContrctRefundIncomeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.contrctrefund.mapper.HouseContrctRefundMapper;
import com.ruoyi.contrctrefund.domain.HouseContrctRefund;
import com.ruoyi.contrctrefund.service.IHouseContrctRefundService;
import org.springframework.transaction.annotation.Transactional;

import javax.management.relation.RoleList;

/**
 * 退租Service业务层处理
 * 
 * @author hct
 * @date 2022-02-16
 */
@Service
public class HouseContrctRefundServiceImpl implements IHouseContrctRefundService 
{
    @Autowired
    private HouseContrctRefundMapper houseContrctRefundMapper;

    @Autowired
    private HouseContarctMapper houseContarctMapper;

    @Autowired
    private HouseInfoMapper houseInfoMapper;

    @Autowired
    private HouseContarctBillMapper houseContarctBillMapper;

    @Autowired
    private HouseContarctIncomeMapper houseContarctIncomeMapper;

    @Autowired
    private HouseContrctRefundIncomeMapper houseContrctRefundIncomeMapper;

    @Autowired
    private IHouseContarctService houseContarctService;

    @Autowired
    private HouseContarctApplyRecordMapper houseContarctApplyRecordMapper;

    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    //读锁   查询方法
    private final Lock r = rwl.readLock();
    //写锁   写库方法
    private final Lock w = rwl.writeLock();



    /**
     * 查询退租
     * 
     * @param id 退租主键
     * @return 退租
     */
    @Override
    public HouseContrctRefund selectHouseContrctRefundById(Long id)
    {
        return houseContrctRefundMapper.selectHouseContrctRefundById(id);
    }

    /**
     * 查询退租列表
     * 
     * @param houseContrctRefund 退租
     * @return 退租
     */
    @Override
    public List<HouseContrctRefund> selectHouseContrctRefundList(HouseContrctRefund houseContrctRefund)
    {
        return houseContrctRefundMapper.selectHouseContrctRefundList(houseContrctRefund);
    }

    /**
     * 新增退租
     * 
     * @param houseContrctRefund 退租
     * @return 结果
     */
    @Override
    public int insertHouseContrctRefund(HouseContrctRefund houseContrctRefund,Long userId,String userName)
    {
        Date now = new Date();
        Long contractid = houseContrctRefund.getContractid();
        HouseContarct houseContarct = houseContarctMapper.selectHouseContarctById(contractid);
        houseContarct.setContarctStatus(ContarctStatusType.WRENT.getCode());
        houseContarctMapper.updateHouseContarct(houseContarct);
        houseContrctRefund.setCreateTime(now);
        houseContrctRefund.setUpdateTime(now);
        houseContrctRefund.setConfirmStatus(RefundApplyType.NOAPPLY.getCode());
        //添加记录
        HouseContarctApplyRecord applyRecord = new HouseContarctApplyRecord();

        applyRecord.setContarctId(houseContarct.getId());
        applyRecord.setOperTime(now);
        applyRecord.setOperType(ContarctOperType.CREATEREFUND.getCode());
        applyRecord.setOperSonType(ContarctOperResType.CONFIRM.getCode());
        applyRecord.setOperDetail("用户申请退租");
        applyRecord.setOperUserId(userId);
        applyRecord.setOperUserName(userName);
        applyRecord.setCreateBy(userName);
        applyRecord.setCreateTime(now);
        applyRecord.setUpdateBy(userName);
        applyRecord.setUpdateTime(now);
        applyRecord.setRemark("用户申请退租");

        houseContarctApplyRecordMapper.insertHouseContarctApplyRecord(applyRecord);
        return houseContrctRefundMapper.insertHouseContrctRefund(houseContrctRefund);
    }

    /**
     * 修改退租
     * 
     * @param houseContrctRefund 退租
     * @return 结果
     */
    @Override
    public int updateHouseContrctRefund(HouseContrctRefund houseContrctRefund)
    {
        return houseContrctRefundMapper.updateHouseContrctRefund(houseContrctRefund);
    }

    /**
     * 批量删除退租
     * 
     * @param ids 需要删除的退租主键
     * @return 结果
     */
    @Override
    public int deleteHouseContrctRefundByIds(Long[] ids)
    {
        return houseContrctRefundMapper.deleteHouseContrctRefundByIds(ids);
    }

    /**
     * 删除退租信息
     * 
     * @param id 退租主键
     * @return 结果
     */
    @Override
    public int deleteHouseContrctRefundById(Long id)
    {
        return houseContrctRefundMapper.deleteHouseContrctRefundById(id);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object finishContrct(HouseContrctRefund houseContrctRefund,Long userId) throws Exception {
        //创建退单
        Date now = new Date();
        houseContrctRefund.setCreateTime(now);
        houseContrctRefund.setUpdateTime(now);
        houseContrctRefund.setConfirmStatus(RefundApplyType.NOAPPLY.getCode());
        houseContrctRefundMapper.insertHouseContrctRefund(houseContrctRefund);
        return houseContrctRefund;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object confirmContrctRefund(Long refundId,Long userId,String userName) throws Exception {
        Date now = new Date();
        HouseContrctRefund houseContrctRefund = houseContrctRefundMapper.selectHouseContrctRefundById(refundId);
        houseContrctRefund.setConfirmStatus(RefundApplyType.PASS.getCode());
        houseContrctRefund.setConfirmDate(now);
        houseContrctRefund.setConfirmUserName(userName);
        houseContrctRefund.setConfirmId(userId);
        houseContrctRefundMapper.updateHouseContrctRefund(houseContrctRefund);

        Long contractid = houseContrctRefund.getContractid();
        HouseContarct houseContarct = houseContarctMapper.selectHouseContarctById(contractid);
        String roomids = houseContarct.getRoomids();
        String[] roomidArr = roomids.split(",");
        List<Long> updatehiIds = new ArrayList<>();
        for (int i=0;i< roomidArr.length;i++){
            long hid = Long.parseLong(roomidArr[i]);
            updatehiIds.add(hid);
        }
        HouseInfo houseInfoUpdateParam = new HouseInfo();
        houseInfoUpdateParam.setHouseStatus(HouseStatusType.NORENT.getCode());
        houseInfoUpdateParam.setIsMarketable(HouseMarketableType.UP.getCode());
        houseInfoMapper.updateHouseInfoList(houseInfoUpdateParam,updatehiIds);
        //修改合同状态
        houseContarct.setContarctStatus(ContarctStatusType.WRENT.getCode());
        houseContarctMapper.updateHouseContarct(houseContarct);
        //修改所有未完结状态
        HouseContarctBill billParam = new HouseContarctBill();
        List<HouseContarctBill> houseContarctBills = houseContarctBillMapper.selectHouseContarctBillList(billParam);
        List<Long> billIds = new ArrayList<>();
        for (HouseContarctBill bill: houseContarctBills
             ){
            billIds.add(bill.getId());
        }
        HouseContarctBill updbillParam = new HouseContarctBill();
        updbillParam.setIsover(ContarctBillSettleType.HASSETTLE.getCode());
        updbillParam.setRefundStatus(Long.parseLong(BillRefundStatusType.HASREFUNDSETTLE.getCode()+""));
        updbillParam.setStatus(Long.parseLong(BillStatusType.BILLDISABLE.getCode()+""));
        houseContarctBillMapper.updateBillForRF(updbillParam,billIds);
        //获取所有账单下的支付明细
        Long [] billIdArr = new Long[billIds.size()];
        billIds.toArray(billIdArr);
        List<HouseContarctIncome> houseContarctIncomes = houseContarctIncomeMapper.selectHouseContarctIncomeByIds(billIdArr);
        List<HouseContrctRefundIncome> rfincomeList = new ArrayList<>();
        for (HouseContarctIncome income : houseContarctIncomes
             ){
            if(income == null || income.getFee() == null || income.getYsfee() == null){
                continue;
            }
            //将未完成结算的单据写入退单明细
            if(income.getFee().compareTo(income.getYsfee()) != 0){
                HouseContrctRefundIncome refundIncome = new HouseContrctRefundIncome();
                refundIncome.setContrctId(houseContrctRefund.getContractid());
                refundIncome.setRefundBillId(houseContrctRefund.getId());
                refundIncome.setRefundType(income.getFeetype());
                refundIncome.setRefundFee(income.getFee());
                refundIncome.setFeeType(income.getFeetype());
                refundIncome.setFeeTypeId(income.getFeetypeid().intValue());
                refundIncome.setCreateBy(userName);
                refundIncome.setCreateTime(now);
                refundIncome.setUpdateBy(userName);
                refundIncome.setUpdateTime(now);
                rfincomeList.add(refundIncome);
//                houseContrctRefundIncomeMapper.insertHouseContrctRefundIncome(refundIncome);
            }
        }
        if(rfincomeList != null && rfincomeList.size() > 0){
            int i = houseContrctRefundIncomeMapper.insertRfIncomeList(rfincomeList);
        }

        //添加记录
        HouseContarctApplyRecord applyRecord = new HouseContarctApplyRecord();

        applyRecord.setContarctId(houseContarct.getId());
        applyRecord.setOperTime(now);
        applyRecord.setOperType(ContarctOperType.REFUNDAPPLY.getCode());
        applyRecord.setOperSonType(ContarctOperResType.CONFIRM.getCode());
        applyRecord.setOperDetail("退租单审核通过");
        applyRecord.setOperUserId(userId);
        applyRecord.setOperUserName(userName);
        applyRecord.setCreateBy(userName);
        applyRecord.setCreateTime(now);
        applyRecord.setUpdateBy(userName);
        applyRecord.setUpdateTime(now);
        applyRecord.setRemark("退租单审核通过");

        houseContarctApplyRecordMapper.insertHouseContarctApplyRecord(applyRecord);
        return houseContrctRefund;
    }


    @Override
    public Object getContrctRefundAllData(Long refundId) throws Exception {
        HouseContrctRefund houseContrctRefund = houseContrctRefundMapper.selectHouseContrctRefundById(refundId);
        HouseContarct contarctData = (HouseContarct) houseContarctService.contarctDetailForSettle(houseContrctRefund.getContractid());
        houseContrctRefund.setContarctData(contarctData);
        return houseContrctRefund;
    }
}
